/*    Copyright 2010 Tobias Marschall
 *
 *    This file is part of MoSDi.
 *
 *    MoSDi is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    MoSDi is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with MoSDi.  If not, see <http://www.gnu.org/licenses/>.
 */

package mosdi.paa;

import mosdi.fa.AutomataUtils;
import mosdi.fa.Partition;

/** Minimal {@link DAA} that can be constructed from a {@link MinimizableDAA}. */
public class MinimizedDAA extends DAA {

	private DAA daa;
	private Partition equivalencePartition;
	
	public MinimizedDAA(MinimizableDAA daa) {
		this.daa = daa;
		equivalencePartition = AutomataUtils.minimize(daa);
	}
	
	/** Returns the partition of the state space of the underlying (unminimized) DAA given
	 *  at construction time into sets of equivalent states. Each set in the returned partition 
	 *  corresponds to one state of this minimized DAA.
	 */
	public Partition getEquivalencePartition() {
		return equivalencePartition;
	}

	@Override
	public int getAlphabetSize() {
		return daa.getAlphabetSize();
	}

	@Override
	public int getEmission(int state) {
		return daa.getEmission(equivalencePartition.representative(state));
	}

	@Override
	public int getEmissionCount() {
		return daa.getEmissionCount();
	}

	@Override
	public int getStartState() {
		return equivalencePartition.getBlockIndex(daa.getStartState());
	}

	@Override
	public int getStartValue() {
		return daa.getStartValue();
	}

	@Override
	public int getStateCount() {
		return equivalencePartition.blockCount();
	}

	@Override
	public int getTransitionTarget(int state, int character) {
		int target = daa.getTransitionTarget(equivalencePartition.representative(state), character); 
		return equivalencePartition.getBlockIndex(target);
	}

	@Override
	public int getValueCount() {
		return daa.getValueCount();
	}

	@Override
	public int performOperation(int state, int value, int emission) {
		return daa.performOperation(equivalencePartition.representative(state), value, emission);
	}

}
